package com.rayc.mall.logistic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rayc.mall.api.client.AddressClient;
import com.rayc.mall.api.client.OrderClient;
import com.rayc.mall.api.dto.AddressDTO;
import com.rayc.mall.api.dto.OrderDTO;
import com.rayc.mall.common.exception.BizIllegalException;
import com.rayc.mall.common.utils.BeanUtils;
import com.rayc.mall.common.utils.CollUtils;
import com.rayc.mall.common.context.UserContext;
import com.rayc.mall.logistic.domain.po.OrderLogistics;
import com.rayc.mall.logistic.domain.query.LogisticsPageQuery;
import com.rayc.mall.logistic.domain.vo.OrderLogisticsVO;
import com.rayc.mall.logistic.mapper.OrderLogisticsMapper;
import com.rayc.mall.logistic.service.IOrderLogisticsService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @Author: Ray-C
 * @CreateTime: 2025-03-25
 * @Description: 订单物流service实现
 * @Version: 1.0
 */
@Service
@RequiredArgsConstructor
public class OrderLogisticsServiceImpl extends ServiceImpl<OrderLogisticsMapper, OrderLogistics> implements IOrderLogisticsService {

    //    private final AddressMapper addressMapper;
    private final AddressClient addressClient;
    //    private final OrderMapper orderMapper;
    private final OrderClient orderClient;

    public static Long generateLogisticsNumber() {
        // 获取当前日期的年月日
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
        String datePart = dateFormat.format(new Date());

        // 生成12位序列号，这里简化为随机数
        Random random = new Random();
        long l = random.nextLong();
        if (l < 0) {
            l = -l;
        }
        String serialNumber = String.format("%012d", l % 1000000000000L);

        // 返回完整的18位订单号
        return Long.parseLong(datePart + serialNumber);
    }

    @Override
    // 该方法会被feign调用，且调用时位于事务中，需要补充事务注解
    @Transactional(rollbackFor = Exception.class)
    public void createLogistics(OrderDTO order) {
        // 获取地址信息
        Long addressId = order.getAddressId();
        AddressDTO address = addressClient.queryById(addressId).getData();
        if (address == null) {
            throw new BizIllegalException("用户未添加地址信息");
        }
        // 拷贝信息
        OrderLogistics orderLogistics = BeanUtils.copyBean(address, OrderLogistics.class);
        orderLogistics.setOrderId(order.getId());
        // 物流单号和信息
        orderLogistics.setLogisticsNumber(generateLogisticsNumber());
        orderLogistics.setLogisticsCompany("Default Logistics Company");
        LocalDateTime now = LocalDateTime.now();
        orderLogistics.setCreateTime(now);
        orderLogistics.setUpdateTime(now);
        // 保存
        save(orderLogistics);
    }

    @Override
    public List<OrderLogisticsVO> queryMyLogistics() {
        // 获取本人订单列表
        //        QueryWrapper<OrderDTO> orderQueryWrapper = new QueryWrapper<>();
        //        orderQueryWrapper.lambda().eq(OrderDTO::getUserId, UserContext.getUser());
        List<OrderDTO> orders = orderClient.queryByUserId(UserContext.getUser()).getData();
        if (orders == null || orders.isEmpty()) {
            return CollUtils.emptyList();
        }
        List<Long> orderIds = orders.stream().map(OrderDTO::getId).collect(Collectors.toList());
        // 获取这些订单对应的物流信息
        QueryWrapper<OrderLogistics> orderLogisticsQueryWrapper = new QueryWrapper<>();
        orderLogisticsQueryWrapper.lambda().in(OrderLogistics::getOrderId, orderIds);
        List<OrderLogistics> list = list(orderLogisticsQueryWrapper);
        return BeanUtils.copyList(list, OrderLogisticsVO.class);
    }

    @Override
    public Page<OrderLogistics> search(LogisticsPageQuery query) {
        return lambdaQuery()
                .eq(query.getOrderId() != null, OrderLogistics::getOrderId, query.getOrderId())
                .eq(query.getLogisticsNumber() != null, OrderLogistics::getLogisticsNumber, query.getLogisticsNumber())
                .page(query.toMpPage("update_time", false));
    }
}
